<?php declare(strict_types=1);

namespace App\Http\Controller;

use App\Model\Entity\DeviceCmd;
use Swlib\Http\ContentType;
use Swlib\SaberGM;
use Swlib\Saber;
use App\Model\Entity\LogIn;
use App\Model\Entity\Sensor as SensorData_Table;
use App\Model\Entity\SensorData;
use App\Model\Entity\Device;
use App\Model\Entity\Product;
use App\Model\Entity\SensorType;
use App\Model\Entity\ProductSensorType;
use ReflectionException;
use Swoft\Bean\Exception\ContainerException;
use Swoft\Db\Exception\DbException;
use Swoft\Exception\SwoftException;
use Swoft\Http\Message\Response;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Swoft\Log\Helper\Log;

/**
 * Class HelloController
 * @Controller("/v1/sensor_data")
 * @package App\Http\Controller
 */
class SensorDataController
{


    /**
     * @RequestMapping("/v1/sensor_data")
     *
     * @throws DbException
     * @throws SwoftException
     */
    public function index(): Response
    {
        $request = Context()->getRequest();
        $response = Context()->getResponse();

        $mentod = $request->getMethod();

        $headers = $request->getHeaders();



        Log::info($request->raw());
        if($mentod == "POST")
            $data = $request->post();
        else {
            $this->log_w("Error!");
            return $response->withStatus(404);
        }

        $this->log_w(json_encode($data));
        if(isset($data["notifyType"]) && $data["notifyType"] == "deviceDatasChanged") {
            $service = $data["services"];

                $SensorData_t = SensorData_Table::new();
                $SensorData_t->setDeviceId($data["deviceId"]);
                $connectivity = $this->find_array_key($service,"serviceId","Connectivity");
                $sensorData = $this->find_array_key($service,"serviceId","sensorData");
                if($connectivity != null && $sensorData != null) {

                        $datetime = $connectivity["eventTime"];
                        $SensorData_t->setDate($this->toDtae($datetime));
                        $SensorData_t->setSignalPower($connectivity["data"]["SignalPower"]);
                        $SensorData_t->setEcl($connectivity["data"]["ECL"]);
                        $SensorData_t->setSnr($connectivity["data"]["SNR"]);
                        $SensorData_t->setCellID($connectivity["data"]["CellID"]);

                        $SensorData_t->setBattery($sensorData["data"]["battery"]);
                        $SensorData_t->setData(json_encode($sensorData["data"]["json"]));
                    try {
                        $SensorData_t->save();
                    } catch (ReflectionException $e) {
                        Log::error($e->getMessage());
                    } catch (ContainerException $e) {
                        Log::error($e->getMessage());
                    } catch (DbException $e) {
                        Log::error($e->getMessage());
                    }
                    //处理传感器数据并保存
                    $this->save_sensorData($SensorData_t->getId(),$sensorData["data"]["json"]);
                }
        }
        else
        {
            return $response->withStatus(404);
        }



        return $response->withData($data);
    }

    /**
     * 电信时间格式转换
     * @param $str string
     * @return string
     */
    public function toDtae($str)
    {
        $y = substr($str,0,4);
        $m = substr($str,4,2);
        $d = substr($str,6,2);
        $h = substr($str,9,2);
        $M = substr($str,11,2);
        $s = substr($str,13,2);
        return "$y-$m-$d $h:$M:$s";
    }


    /**
     * 在数组中查找对象中$key 为$name的值对象
     * @param $services
     * @param $name
     * @param $key
     * @return mixed|null
     */
    private function find_array_key($services,$key,$name)
    {
        foreach ($services as $v)
        {
            if(isset($v[$key]) && $v[$key] == $name)
            {
                return $v;
            }
        }
        return null;
    }

    /**
     * 处理传感器数据
     * @param $id //sensoe表数据id
     * @param $data
     * @throws DbException
     */
    private function save_sensorData($id,$data)
    {
        if(isset($data["productId"]) && isset($data["deviceId"])
            && isset($data["type"])  && $data["type"] == "Sensor" && isset($data["SensorData"]))
        {

            $productID = Product::where("productId",$data["productId"]);
            $deviceIdD = Device::where("deviceId",$data["deviceId"]);
            if($productID->get()->count() > 0 && $deviceIdD->get()->count() > 0)
            {

                $ProductSensorType = ProductSensorType::where("productId",$data["productId"]);
                if($ProductSensorType->get()->count() > 0)
                {


                    foreach ($ProductSensorType->get() as $type_name)
                    {
                            $SensorData = $this->find_array_key($data["SensorData"],"SensorName",$type_name["type_name"]);

                            if($SensorData != null)
                            {
                                foreach ($SensorData["Data"] as $v)
                                {


                                    $sensorData = SensorData::new();
                                    $sensorData->setSourceId($id);
                                    $sensorData->setProductId($data["productId"]);
                                    $sensorData->setDeviceId($data["deviceId"]);

                                    $sensorData->setType_name($type_name["type_name"]);
                                    if(isset($SensorData["SensorNum"]) && $SensorData["SensorNum"] != "")
                                        $sensorData->setSensorNum((int)$SensorData["SensorNum"]);
                                    else {
                                        continue;
                                    }
                                    if(isset($v["value"]) && $v["value"] != "")
                                        $sensorData->setData($v["value"]);
                                    else {
                                        continue;
                                    }
                                    if(isset($v["time"]) && $v["time"] != "")
                                        $sensorData->setDate($v["time"]);
                                    else
                                        $sensorData->setDate(date("Y-m-d H:i:s"));
                                    try {
                                        $sensorData->save();
                                    } catch (ReflectionException $e) {
                                        Log::error($e->getMessage());
                                    } catch (ContainerException $e) {
                                        Log::error($e->getMessage());
                                    } catch (DbException $e) {
                                        Log::error($e->getMessage());
                                    }

                                }

                            }
                    }




                    //
                }


            }
        }
    }

    /**
     * @RequestMapping("/v1/deviceCommandsReply")
     * @throws SwoftException
     */
    public function deviceCommandsReply(): Response
    {


        $request = Context()->getRequest();
        $response = Context()->getResponse();

        $mentod = $request->getMethod();

        $headers = $request->getHeaders();


        if ($mentod == "POST")
            $data = $request->post();
        else {
            Log::error("Error!");
            return $response->withStatus(404);

        }
        if(!isset($data["commandId"]))
            return $response->withStatus(404);
        if(!isset($data["result"]["resultCode"]))
            return $response->withStatus(404);
        if(!isset($data["result"]["resultDetail"]["response"]))
            return $response->withStatus(404);


        try{
            $recdb = DeviceCmd::where("NB_cmdId",$data["commandId"])->orderBy("sendDate","desc");
            if($recdb->count() > 0)
            {
                $recdb->update(["recDate"=>date("Y-m-d H:i:s"),"resultCode"=>$data["result"]["resultCode"],"return"=>json_encode($data["result"]["resultDetail"]["response"])]);
            }
        } catch (ReflectionException $e) {
        return $response->withStatus(400)->withData(["error"=>"5","errorMsg"=>$e->getMessage()]);
        } catch (ContainerException $e) {
            return $response->withStatus(400)->withData(["error"=>"5","errorMsg"=>$e->getMessage()]);
        } catch (DbException $e) {
            return $response->withStatus(400)->withData(["error"=>"5","errorMsg"=>$e->getMessage()]);
        }
        //$this->log_w(json_encode($data));
        $rec = json_encode($data);
        return $response->withData(stripslashes($rec));
    }

    /**
     * 写日志
     * @param $data
     * @throws DbException
     */
    private function log_w($data)
    {
        $Log = LogIn::new();
        $Log->setDate(date("Y-m-d H:i:s"));
        $Log->setLog((string)$data);
        try {
            $Log->save();
        } catch (ReflectionException $e) {
            Log::error($e->getMessage());
        } catch (ContainerException $e) {
            Log::error($e->getMessage());
        } catch (DbException $e) {
            Log::error($e->getMessage());
        }
    }


}
